import Device from 'device';
import EventEmitter from 'events';
import { IDeviceReport, IDeviceType, ISimpleDevice } from '../interfaces/device.interface';

export type IController = Device;

class DeviceManager extends EventEmitter {
  public devMap: Map<string, ISimpleDevice>;
  public controllerMap: Map<string, IController>;

  constructor() {
    super();
    this.devMap = new Map();
    this.controllerMap = new Map();
    this.init();
  }

  init() {
    // 获取当前所有所有设备！
    Device.list(true, (error, list) => {
      if (error) {
        console.error('Device.list error!' + error);
        return this.emit('error', '页面异常，请刷新或退出页面重试！');
      } else {
        this.devMap.clear();
        list.map((item) => {
          Device.info(item.devid, (error, info) => {
            if (error) {
              console.error('Device.info error!' + error);
              this.emit('error', `设备 ${item.alias} 信息初始化失败, 请刷新重试！`);
            } else {
              const type = this.getDeviceType(info.report);
              this.devMap.set(item.devid, {
                devid: item.devid,
                alias: info.alias,
                type
              });
            }
          });
        });
      }
    });
    Device.on('join', (devid, info) => {
      const type = this.getDeviceType(info.report);
      const dev = {
        devid,
        alias: info.alias,
        type
      };
      this.devMap.set(devid, dev);
      this.emit('join', dev);
    });
    Device.on('lost', (devid) => {
      // 删除控制器
      if (this.controllerMap.has(devid)) {
        this.controllerMap.delete(devid);
      }
      const lostDev = this.devMap.get(devid);
      if (!devid || !lostDev) {
        /* 这里的话，有时候会为空 */
        return this.emit('error', '设备丢失出错异常，请刷新页面！');
      }
      this.emit('lost', lostDev);
    });
  }

  /* 构建设备控制对象 */
  generateController(devid: string): Promise<Device> {
    if (this.controllerMap.has(devid)) {
      return Promise.resolve(this.controllerMap.get(devid));
    }
    const controller = new Device();
    return new Promise((resolve, reject) => {
      controller.request(devid, (error) => {
        if (error) {
          reject(error);
        } else {
          this.controllerMap.set(devid, controller);
          resolve(controller);
        }
      });
    });
  }

  /* 删除控制器 */
  deleteController(devid: string) {
    this.controllerMap.delete(devid);
  }

  /* 发送设备消息 */
  sendDeviceInfo(devid: string, data: any) {
    const controller = this.controllerMap.get(devid);
    if (!controller) {
      console.error('Controller does not exist');
      return Promise.reject('程序出现未知错误，请退出重试！');
    }
    return new Promise((resolve, reject) => {
      controller.send(
        data,
        (err) => {
          if (err) {
            console.error('sendDeviceInfo error: ', err);
            reject('控制设备失败，请重试！');
          } else {
            resolve({});
          }
        },
        0
      );
    });
  }

  /* 获取设备类型 */
  getDeviceType(report: IDeviceReport): IDeviceType | undefined {
    const { type, model } = report;
    if (type === 'light.rc' && model === 'IDDGYK01B') {
      return 'light-control'; // 单灯控（后面可能没有）
    } else if (type === 'device.ac' && model === 'IDAC01B') {
      return 'ac-control'; // 单空调控
    } else if (type === 'device.micro' && model === 'IDMICRO01B') {
      return 'body-sensor'; // 单人体
    } else if (type === 'device.illu' && model === 'IDILLU01B') {
      return 'illu-sensor'; // 单光照（后面可能没有）
    } else if (type === 'device.monitor' && model === 'IDMONITOR01B') {
      return 'body-illu-sensor'; // 复合（人体 + 光照）
    } else if (type === 'device.ctrl' && model === 'IDCTRL01B') {
      return 'light-ac-control'; // 复合（灯控 + 空调控制）
    }
  }
}

const devManager = new DeviceManager();

export default devManager;
